package com.windliven.spoc.modules.init.config;

import com.windliven.spoc.modules.init.common.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @Author: bysun
 * @Date: 2019/5/14 17:09
 */
@Controller
public class GlobalErrorHandler implements ErrorController {
    //错误信息页
    public static final String ERROR_PATH = "/error";

    @Autowired
    private ErrorAttributes errorAttributes;

    @RequestMapping(value = ERROR_PATH, produces = "text/html")
    public String exceptionHandler(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == 401) {
            return "/401";
        } else if (statusCode == 404) {
            return "/404";
        } else if (statusCode == 403) {
            return "/403";
        } else {
            return "/500";
        }
    }

    /**
     * 根据业务规则,统一处理异常。
     */
    @RequestMapping(ERROR_PATH)
    @ResponseBody
    public ApiResponse errorHandler(HttpServletRequest request) {
        ServletWebRequest webRequest = new ServletWebRequest(request);
        Map<String, Object> errorAttributesMap = this.errorAttributes.getErrorAttributes(webRequest, false);
        int statusCode = getStatus(request);

        return ApiResponse.ofMessage(statusCode, String.valueOf(errorAttributesMap.getOrDefault("message", "error")));
    }

    private int getStatus(HttpServletRequest request) {
        Integer status = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (status != null) {
            return status;
        }

        return 500;
    }

    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }
}